home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianSIMSFiles.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
100KB
|
3,397 lines
/*ScianSIMSFiles.c
File readers for Steacie Institute of Molecular Sciences
National Research Council of Canada
Christina Lam
Summer Student
August 1993
email: lamchri@ecf.utoronto.ca (until May 1, 1994)
XYZ, GRD, GSN1, GSN2, GSN file readers
XYZ: ball/stick molecules in XMol's XYZ file format
GRD: reads BioSym's DMol PLOT 3d grid files
GSN1,GSN2: molecular orbitals from gaussian primitives
GSN: takes Gaussian92 output, generates molecular orbitals
for standard N-M1G basis sets, generates ball/stick
molecule
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianWindows.h"
#include "ScianControls.h"
#include "ScianTextBoxes.h"
#include "ScianFiles.h"
#include "ScianLists.h"
#include "ScianPictures.h"
#include "ScianErrors.h"
#include "ScianTimers.h"
#include "ScianDatasets.h"
#include "ScianIDs.h"
#include "ScianStyle.h"
#include "ScianSciences.h"
#include "ScianArrays.h"
#include "ScianTemplates.h"
#include "ScianTitleBoxes.h"
#include "ScianButtons.h"
#include "ScianColors.h"
#include "ScianSIMSFiles.h"
extern ObjPtr visBalls, visGeometryClass;
/* ---------------------------------
XYZ file reader
This reader takes a file in the XYZ Cartesian molecular model
format as specified by XMol (Copyright 1991 Research Equipment
Inc. dba Minnesota Supercomputer Center). Three datasets,
which may be time-dependent, are then created:
"name.atoms", "name.radii", and "name.form".
The dataset, "name.atoms", may then be used to visualize/animate
the molecule in ball-and/or-stick form using the Balls or Sticks
visualization objects. The distance required for an inter-atomic bond
to be shown is determined by one of two methods:
1) the sum of the covalent radii, multiplied by a scale factor
2) an arbitrary (constant) value
As in the PDB reader, the size and colour of the balls and sticks are
determined by the atomic number & radius.
---------------------------------- */
/* ----------------------------------
Converts XYZ name to atomic number
---------------------------------- */
#ifdef PROTO
int AtomXYZNameToNumber(char *name)
#else
int AtomXYZNameToNumber(name)
char *name;
#endif
/*Finds the atomic number for atom name. Returns it or 0*/
{
int k;
for (k = 0; k < N_XYZ_SYMBOLS; ++k)
{
if (0 == strcmp(name, xyzSymbolTable[k] . name))
{
return xyzSymbolTable[k] . atomicNumber;
}
}
/* if not found yet, check user-defined atoms */
for (k=0; k < numExtraXYZSymbols; k++)
{
if (0 == strcmp(name, xyzExtraSymbolTable[k] . name))
{
return xyzExtraSymbolTable[k] . atomicNumber;
}
}
return 0;
}
#define MISRAD -1.0 /* Need to put one declaration somewhere*/
#define STICKRADIUS 0.15
#define MAXSTICKLENGTH 1.7
#define CALC_COVALENTRADII 0 /* flag to calc bonds by covalent radii method */
#define CALC_MAXSTICK 1 /* flag to calc bonds by arbitrary stick length */
#define FUDGEFACTOR 1.0
/*Ball style flags*/
#define BS_JACKS 2
#define BS_CUBES 4
#define BS_OCTOHEDRA 8
#define BS_SPHERES 16
/* -----------------------------------
XYZ file reader
modified from PDB file reader
Format specification:
"The XYZ format supports multi-step datasets. Each step is
represented by a two-line "header," followed by one line for
each atom.
The first line of a step's header is the number of atoms in
that step. This integer may be preceded by whitespace; any-
thing on the line after the integer is ignored. The second
line of the header leaves room for a descriptive string.
This line may be blank, or it may contain some information
pertinent to that particular step, but it _m_u_s_t exist, and it
_m_u_s_t be just one line long.
Each line of text describing a single atom must contain at
least four fields of information, separated by whitespace:
the atom's type (a short string of alphanumeric characters),
and its x-, y-, and z-positions. Optionally, extra fields
may be used to specify a charge for the atom, and/or a vec-
tor associated with the atom. If an input line contains
five or eight fields, the fifth field is interpreted as the
atom's charge; otherwise, a charge of zero is assumed. If
an input line contains seven or eight fields, the last three
fields are interpreted as the components of a vector. These
components should be specified in angstroms."
(XYZ man pages, Minnesota Supercomputer Centre, 1991)
----------------------------------- */
#ifdef PROTO
static ObjPtr ReadXYZFile(ObjPtr reader, char *name)
#else
static ObjPtr ReadXYZFile(reader,name)
ObjPtr reader;
char *name;
#endif
{
/* -----------------------------------
Variables for dataset and data form
----------------------------------- */
real curTime = 0.0; /* keeps track of current animation frame */
char extension[5]; /* auto-numbering extension to dataset name*/
/* if same dataset opened more than once */
/* NOTE: important to have new names for each dataset and form */
char atomsName[80], radiiName[80], tmpName[80],formName[80];
char *tc; /* terminating character */
real bounds[6]; /* xmin, xmax, ymin, .... */
long dims[2]; /* dimension vector for unstructured data form */
ObjPtr formVectors, dataForm, atomicNumberDataset, radiusDataset;
/* -----------------------------------
Variables for file input and parsing
----------------------------------- */
char cmdStr[256];
FILE *inFile;
real field5, field6, field7, field8; /* store optional xyz fields of information*/
char s[4];
char atomNameBuf[4];
/* -----------------------------------
Variables for atoms
----------------------------------- */
long numAtoms; /* number of atoms per frame */
atomData *currentAtoms; /* points to array of data for current atoms read */
float centre[3]; /* coords of centre of atom */
real ballScaleFactor;
/* -----------------------------------
Variables for bonds
----------------------------------- */
long nBonds = 0; /* number of bonds guessed */
TwoReals *bondsBuffer = 0;
long nBondsAllocated = 0;
real maxStickLength;
ObjPtr var;
real sum, temp;
real covalentRadius1, covalentRadius2, scaleFactor;
int bondCalcType; /* method used to calculate minimum interatomic dist for bond*/
long i, j,k, count; /* counters*/
Bool convertToAngstroms; /* false if already in angstroms, true otherwise */
/* -------------------------------------
From the file reader controls, get:
-value of the arbitrary maximum bond length
-bond guessing method
-covalent radii fudge factor
-ball radius scale factor
-state of units conversion checkbox
------------------------------------- */
var = GetRealVar("ReadXYZFile", reader, USER1);
if (!var)
maxStickLength = MAXSTICKLENGTH;
else
maxStickLength = GetReal(var);
if ((var = GetIntVar("ReadXYZFile", reader, USER3)) == NULLOBJ)
{
bondCalcType = CALC_COVALENTRADII;
}
else
{
bondCalcType = GetInt(var);
}
if ((var = GetRealVar("ReadXYZFile", reader, USER4)) == NULLOBJ)
{
scaleFactor = FUDGEFACTOR;
}
else
{
scaleFactor = GetReal(var);
}
if ((var = GetRealVar("ReadXYZFile", reader, USER5)) == NULLOBJ)
{
ballScaleFactor = 1.0;
}
else
{
ballScaleFactor = GetReal(var);
}
convertToAngstroms = GetPredicate(reader, USER6) ? true : false;
/* ------------------------------------
read the file in
------------------------------------- */
inFile = fopen(name, "r");
if (!inFile)
{
Error("ReadXYZFile", OPENFILEERROR, name);
return NULLOBJ;
}
/* -------------------------------------
make names for datasets
------------------------------------- */
strcpy (tmpName, name);
tc = tmpName;
while(*tc && (*tc != '@') && (*tc != '.'))
tc++;
*tc = '\0';
strcpy(atomsName, tmpName);
strcpy(radiiName, tmpName);
strcpy(formName, tmpName);
strcat(atomsName, ".atoms");
strcat(radiiName, ".radii");
strcat(formName, ".form");
k=1;
strcpy(tmpName, atomsName);
while (FindDatasetByName(tmpName))
{
++k;
sprintf(tmpName, "%s(%d)", atomsName,k);
}
if (k > 1)
{
sprintf(extension, "(%d)", k);
strcat(atomsName, extension);
strcat(radiiName, extension);
strcat(formName, extension);
}
/* ----------------------------------------
make bounds impossible
---------------------------------------- */
bounds[0] = bounds[2] = bounds[4] = PLUSINF;
bounds[1] = bounds[3] = bounds[5] = MINUSINF;
/*------------------------------------------
Read the picture in
------------------------------------------*/
while (fgets(tempStr, 40, inFile)!= NULL)
{
/* First line should have #atoms per frame */
if (1 == sscanf(tempStr, "%s", cmdStr))
{
if (1 != sscanf(tempStr, "%d", &numAtoms))
{
FileFormatError("ReadXYZFile", "# atoms expected");
return NULLOBJ;
}
currentAtoms = (atomData *) Alloc (numAtoms * sizeof(atomData));
if ( currentAtoms == NULL)
{
FileFormatError("ReadXYZFile", "unable to allocate memory \
for atoms");
return NULLOBJ;
}
}
else
{
FileFormatError("ReadXYZFile", "# atoms expected");
return NULLOBJ;
}
/* Skip the second line, which should be just a comment */
ReadLn(inFile);
/* Read a line in for each atom */
for (i = 0; i < numAtoms; i++ )
{
fgets( tempStr, 80, inFile);
/* ----------------------------------
format of each line may be one of:
"name x y z\n"
"name x y z charge\n"
"name x y z vectorX vectorY vectorZ\n"
"name x y z charge vectorX vectorY vectorZ\n"
---------------------------------- */
if (sscanf(tempStr, "%s %g %g %g %g %g %g %g", &s, &(centre[0]), \
&(centre[1]), &(centre[2]), &field5, &field6, &field7, &field8) \
>= 4 )
{
/* -----------------------------
Record atomic name and number
and convert units if necessary
------------------------------ */
strcpy(currentAtoms[i].name, s);
currentAtoms[i].atomicNumber = AtomXYZNameToNumber(currentAtoms[i].name);
for (j = 0; j < 3; j++ )
{
if (convertToAngstroms)
centre[j] *= ANGSTROMS_PER_ALU;
/* store all atom coords for later */
currentAtoms[i].coords[j] = centre[j];
/* revise bounds if necessary */
if ( centre[j] < bounds[j*2] )
bounds[j*2] = centre[j];
if ( centre[j] > bounds[j*2 + 1] )
bounds[j*2 + 1] = centre[j];
}
}
else
{
FileFormatError("ReadXYZFile", "Badly formatted atom");
}
}
nBonds = 0;
nBondsAllocated = 200;
bondsBuffer = (TwoReals *) Alloc(sizeof(TwoReals) * nBondsAllocated);
switch ( bondCalcType )
{
case CALC_COVALENTRADII:
for ( i = 0; i < (numAtoms-1); i++ )
{
covalentRadius1 = atomInfo[currentAtoms[i].atomicNumber-1].covalentRadius;
/* --------------------------------
If either atom is missing the covalent radius data,
do not draw a bond between them.
-------------------------------- */
if (covalentRadius1 != MISRAD)
{
for (j = (i+1); j < numAtoms; j++ )
{
covalentRadius2 = atomInfo[currentAtoms[j].atomicNumber-1].covalentRadius;
if ( covalentRadius2 != MISRAD)
{
sum = 0.0;
for (k = 0; k < 3; k++)
{
temp = currentAtoms[j].coords[k] - \
currentAtoms[i].coords[k];
sum += temp * temp;
}
if (sum <= SQUARE ( (covalentRadius1 + covalentRadius2)*scaleFactor))
{
if (nBonds >= nBondsAllocated)
{
nBondsAllocated += 200;
bondsBuffer = (TwoReals *) Realloc(bondsBuffer,
sizeof(TwoReals) * nBondsAllocated);
}
bondsBuffer[nBonds][0] = i;
bondsBuffer[nBonds][1] = j;
++nBonds;
}
}
}
}
}
break;
case CALC_MAXSTICK:
for ( i = 0; i < (numAtoms-1); i++ )
{
for (j = (i+1); j < numAtoms; j++ )
{
sum = 0.0;
for (k = 0; k < 3; k++)
{
temp = currentAtoms[j].coords[k] - \
currentAtoms[i].coords[k];
sum += temp * temp;
}
if (sum <= SQUARE(maxStickLength))
{
if (nBonds >= nBondsAllocated)
{
nBondsAllocated += 200;
bondsBuffer = (TwoReals *) Realloc(bondsBuffer,
sizeof(TwoReals) * nBondsAllocated);
}
bondsBuffer[nBonds][0] = i;
bondsBuffer[nBonds][1] = j;
++nBonds;
}
}
}
break;
}
/* make datasets */
atomicNumberDataset = NewDataset( atomsName, 1, &numAtoms, 0);
/* this variable signals the palette creation later */
SetVar(atomicNumberDataset, UNITSNAME, NewString("Atomic number"));
radiusDataset = NewDataset( radiiName, 1, &numAtoms, 0 );
/* --------------------------------------
make a vector dataset for the form
-------------------------------------- */
formVectors = NewDataset(formName, 1, &numAtoms, 3);
dims[0] = numAtoms;
dims[1] = nBonds;
if (nBonds > 0)
{ /* one dimensional dataset (points and lines) */
dataForm = NewUnstructuredDataForm(tmpName, 1, dims, bounds,
formVectors);
}
else
{/* zero dimensional dataset (points only)*/
dataForm = NewUnstructuredDataForm(tmpName, 0, dims, bounds,
formVectors);
}
SetDatasetForm(atomicNumberDataset, dataForm);
SetDatasetForm(radiusDataset, dataForm);
/* Fill it all up */
if (nBonds)
{
/*Set the bonds*/
for (k = 0; k < nBonds; ++k)
{
Put1Edge(dataForm, k,
(long) bondsBuffer[k][0], (long) bondsBuffer[k][1]);
}
}
SetCurField(FORMFIELD, formVectors);
SetCurField(FIELD1, atomicNumberDataset);
SetCurField(FIELD2, radiusDataset);
for (i=0; i < numAtoms; i++ )
{
PutFieldComponent(FORMFIELD, 0, &i, currentAtoms[i].coords[0]);
PutFieldComponent(FORMFIELD, 1, &i, currentAtoms[i].coords[1]);
PutFieldComponent(FORMFIELD, 2, &i, currentAtoms[i].coords[2]);
PutFieldComponent(FIELD1, 0, &i, currentAtoms[i].atomicNumber ? (real)
currentAtoms[i].atomicNumber : missingData);
PutFieldComponent(FIELD2, 0, &i, currentAtoms[i].atomicNumber ?
atomInfo[currentAtoms[i].atomicNumber-1].radius : missingData );
}
/* -------------------------
create new variables of SIZEOBJ ID
allows sizing and scaling of atomic radii
-------------------------- */
SetVar(atomicNumberDataset, SIZEOBJ, radiusDataset);
SetVar(radiusDataset, SIZEOBJ, radiusDataset);
SetVar(atomicNumberDataset, POINTSTYLE, NewInt(BS_SPHERES));
/* ------------------------------
Interpolation in time
------------------------------ */
SetVar(atomicNumberDataset, INTERPOLATEP, ObjTrue);
SetVar(radiusDataset, INTERPOLATEP, ObjTrue);
SetVar(formVectors, INTERPOLATEP, ObjTrue);
RegisterTimeDataset ( atomicNumberDataset, curTime );
RegisterTimeDataset ( radiusDataset, curTime );
/* yes I know radii don't change with time */
RegisterTimeDataset ( formVectors, curTime );
curTime += 1.0; /* increment frame count */
Free(currentAtoms);
}
fclose(inFile);
/* ---------------------------------
HACK!
Sets default ball visualization to a sphere instead
of an octohedron. SetVar of POINTSTYLE of
dataset itself doesn't seem to work.
----------------------------------- */
SetVar(visBalls, POINTSTYLE, NewInt(BS_SPHERES));
/* ---------------------------------
MORE HACK!
Set scale factor of balls' size object
---------------------------------- */
SetVar(visBalls, SIZEFACTOR, NewReal(ballScaleFactor));
return NULLOBJ;
}
/* ------------------------------------
Read in extra user-defined symbolic information for XYZ file format
------------------------------------ */
#ifdef PROTO
int ReadExtraXYZSymbolTable (void)
#else
int ReadExtraXYZSymbolTable()
#endif
{
char tempStr[80];
int i, numTypes;
FILE *inFile;
char symbol[3], name[6];
int number;
/* ------------------------------------
read the file in
------------------------------------- */
inFile = fopen(xyzExtraInfoFile, "r");
if (!inFile)
{
/* no extra symbols */
return(0);
}
/* -------------------------------------
first line should have number of types listed in file
------------------------------------- */
if (fgets(tempStr, 80, inFile) == NULL)
return(-1);
if (sscanf(tempStr, "%d", &numTypes) != 1)
return(-1);
/* --------------------------------------
allocate memory to store symbol table
-------------------------------------- */
xyzExtraSymbolTable = (xyzInfo *) Alloc ( numTypes * sizeof (xyzInfo) );
if (xyzExtraSymbolTable == NULL)
return (-1);
for ( i = 0; i < numTypes; i++ )
{
if (fgets(tempStr, 80, inFile) == NULL)
return (-1);
if (sscanf (tempStr, "%s %s %d", symbol, name, &number ) == 3 )
{
strcpy(xyzExtraSymbolTable[i].symbol,symbol);
strcpy(xyzExtraSymbolTable[i].name, name);
xyzExtraSymbolTable[i].atomicNumber = number;
}
else
return(-1);
}
return (numTypes);
}
/* --------------------------------
XYZ File Reader Controls
Modified from AddNXRControls()
-------------------------------- */
#define XYZ_ITEMWIDTH 225
#define XYZ_MIDDLE_SEP 45
#define XYZ_SMALLER_ITEM 180
#define XYZ_RADIOWIDTH 400
#define XYZ_BOXLEFT 325
#define XYZ_BOXWIDTH 60
#ifdef PROTO
static ObjPtr AddXYZControls(ObjPtr FileReader, ObjPtr PanelContents)
#else
static ObjPtr AddXYZControls(FileReader, PanelContents)
ObjPtr FileReader, PanelContents;
#endif
{
ObjPtr titleBox, radio, checkBox, button;
ObjPtr checkbox, textbox, var;
int left, right, bottom, top;
bottom = left = MAJORBORDER;
/*Create the check box for units conversion*/
top = bottom + CHECKBOXHEIGHT;
right = left + FRTIMEWIDTH;
checkBox = NewCheckBox(left, right, bottom, top,
"Coordinates given in atomic length units",
GetPredicate(FileReader, USER6));
SetVar(checkBox, PARENT, PanelContents);
PrefixList(PanelContents, checkBox);
bottom = top + MINORBORDER;
if (!GetVar(FileReader, USER6))
{
SetVar(FileReader, USER6, ObjFalse);
}
AssocDirectControlWithVar(checkBox, FileReader, USER6);
SetVar(checkBox, HELPSTRING,
NewString("If this box is checked, the file reader will consider all \
xyz coordinates to be in ALU and convert all coordinates to Angstroms. \
A conversion factor of 0.5292 Angstroms per ALU is used in the \
calculation."));
/* Pre-set balls scaling factor textbox*/
left = MAJORBORDER;
right = left + XYZ_SMALLER_ITEM;
bottom = top;
top = bottom + EDITBOXHEIGHT;
textbox = NewTextBox(left, right, bottom, top,
0, "Ball Radius Scaling Factor Text", "Ball Radius Scaling Factor:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + XYZ_BOXWIDTH;
var = GetRealVar("AddXYZControls", FileReader, USER5);
if (!var)
SetVar(FileReader, USER5, NewReal(1.0));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"Ball Radius Scaling Factor", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, USER5,
0, plusInf, TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value indicates the scaling factor applied to the radius of \
each atom (ball) in ball-and-stick molecular visualization. This option allows \
the user to pre-set the scale factor of a size object in a balls visualization. For \
example, a user reading in a lot of large organic molecules may want to set \
this value to, say, 0.2."));
left = MAJORBORDER;
bottom = top + MINORBORDER;
/*Do the title box around the radio group*/
right = left + 2 * MINORBORDER + XYZ_RADIOWIDTH;
top = bottom + 2 * MINORBORDER + 1 * CHECKBOXSPACING + 2 \
* CHECKBOXHEIGHT + TITLEBOXTOP;
titleBox = NewTitleBox(left, right, bottom, top, "Calculate Molecular Bonds");
PrefixList(PanelContents, titleBox);
SetVar(titleBox, PARENT, PanelContents);
/*Make the radio buttons*/
radio = NewRadioButtonGroup("Molecular Bonds Radio");
SetVar(radio, PARENT, PanelContents);
SetVar(radio, REPOBJ, FileReader);
PrefixList(PanelContents, radio);
left += MINORBORDER;
right -= MINORBORDER;
top -= TITLEBOXTOP + MINORBORDER;
bottom = top - CHECKBOXHEIGHT;
button = NewRadioButton(left, right, bottom, top, "Sum of covalent radii * scale factor of:");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is down, the minimum \
interatomic distance required for a bond (stick) to be drawn is calculated as the sum of the \
respective covalent radii as defined in ScianPeriodicTable.h multiplied by a scale factor \
(default 1.0)."));
/* scale factor text box */
left = MAJORBORDER + XYZ_BOXLEFT;
right = left + XYZ_BOXWIDTH;
top = bottom + EDITBOXHEIGHT;
var = GetRealVar("AddXYZControls", FileReader, USER4);
if (!var)
SetVar(FileReader, USER4, NewReal(FUDGEFACTOR));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"Scale factor", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, USER4,
0, plusInf, TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the scale factor by which the sum of covalent radii is multiplied \
to determine minimum separation distance required between atoms for a bond (stick) to be drawn. \
I.e. if this value is SF, then the atoms must be at most (covalent_radius1 + covalent_radius2)*SF \
apart for a bond to occur."));
top = bottom - CHECKBOXSPACING;
bottom = top - EDITBOXHEIGHT;
top = bottom + CHECKBOXHEIGHT;
left = MAJORBORDER+MINORBORDER;
button = NewRadioButton(left, right, bottom, top, "Arbitrary maximum stick length of:");
AddRadioButton(radio, button);
SetVar(button, HELPSTRING, NewString("When this button is down, the minimum \
interatomic distance required for a bond (stick) to be drawn is simply the maximum \
stick length."));
/* Maximum stick length setting text box*/
left = MAJORBORDER + XYZ_BOXLEFT;
right = left + XYZ_BOXWIDTH;
top = bottom + EDITBOXHEIGHT;
var = GetRealVar("AddXYZControls", FileReader, USER1);
if (!var)
SetVar(FileReader, USER1, NewReal(MAXSTICKLENGTH));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"Maximum stick length", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, USER1,
0, plusInf, TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value indicates the minimum separation distance required between \
atoms for a bond (stick) to be drawn."));
var = GetIntVar("AddXYZControls", FileReader, USER3);
if (!var) SetVar(FileReader, USER3, NewInt(CALC_COVALENTRADII));
AssocDirectControlWithVar(radio, FileReader, USER3);
SetVar(radio, HELPSTRING, NewString("This radio button group controls how \
the minimum interatomic distance required for a bond is calculated."));
return NULLOBJ;
}
/* -------------------------------------------
GRD file reader
This file reader takes the 3D grid data produced by the PLOT
keyword of BioSym's software, DMol, as described on pages
B-31 to B-35 of the DMol User Manual.
------------------------------------------- */
#ifdef PROTO
static int parseGRDHeader(FILE *infile, gridParameters *p)
#else
static int parseGRDHeader(infile, p)
FILE *infile;
gridParameters *p;
#endif
{
char tempStr[80];
int index;
/* -----------------------------
Parse header, expecting exactly 5 lines
----------------------------- */
ReadLn(infile); /* first line is a comment; ignore */
ReadLn(infile); /* second line is a FORTRAN format description
should be 1F15.10 (one data item per line)
ignore for now */
if (fgets(tempStr, 80, infile) != NULL) /* third line has cell lengths and angles*/
{
if (6 != sscanf( tempStr, "%g %g %g %g %g %g", &p->a,&p->b,&p->c, \
&p->alpha, &p->beta, &p->gamma) )
{
FileFormatError("ReadGRDFile", "Bad format for cell lengths and angles");
return(-1);
}
}
else
{
FileFormatError("ReadGRDFile", "Expected cell lengths and angles");
return(-1);
}
if (fgets(tempStr, 80, infile) != NULL) /* fourth line has #grid spaces*/
{
if (3 != sscanf(tempStr, "%d %d %d", &p->numX, &p->numY, &p->numZ))
{
FileFormatError("ReadGRDFile", "Bad format for grid spaces");
return(-1);
}
}
else
{
FileFormatError("ReadGRDFile", "Expected grid space information");
return(-1);
}
if (fgets(tempStr, 80, infile) != NULL) /* fifth line has fastest varying index*/
{ /* and grid spaces to either side of origin*/
if (7 != sscanf(tempStr, "%d %d %d %d %d %d %d", &(index), &p->xStart, \
&p->xEnd, &p->yStart, &p->yEnd, &p->zStart, &p->zEnd) )
{
FileFormatError("ReadGRDFile", "Bad format for fastest varying index or \
grid spaces to either side of origin");
return(-1);
}
if ( index == 1)
p->xIsFastest = true;
else if (index == 3)
p->xIsFastest = false;
else
{
FileFormatError("ReadGRDFile", "Fastest varying index should be either \
1 or 3");
return(-1);
}
}
else
{
FileFormatError("ReadGRDFile", "Expected fastest varying index and grid \
spaces to either side of origin information");
return(-1);
}
}
#ifdef PROTO
static ObjPtr ReadGRDFile(ObjPtr reader, char *name)
#else
static ObjPtr ReadGRDFile(reader,name)
ObjPtr reader;
char *name;
#endif
/*Reads a GRD file from name*/
{
FILE *infile;
ObjPtr retVal;
ObjPtr dataForm;
ObjPtr gridDataset;
long dims[3];
real bounds[6]; /* Used to define parameters of datasets */
long indices[3]; /* and dataforms */
char formName[80], dataName[80];
char *tc;
gridParameters grid;
real curData;
char tempStr[40];
real min, max, minMax[2];
ObjPtr minMaxArray;
/*---------------------
Derive a dataset name from the file name
--------------------- */
strcpy(formName, name);
tc = formName;
while (*tc && (*tc != '@') && (*tc != '.'))
tc++;
*tc = '\0';
strcpy(dataName, formName);
strcat(formName, ".form");
strcat(dataName, ".data");
/* Open the file and verify that it contains appropriate data */
if ((infile = fopen(name, "r")) == NULL)
{
FileFormatError("ReadGRDFile", "File not accessible");
return NULLOBJ;
}
if (parseGRDHeader(infile, &grid) == -1)
{
FileFormatError("ReadGRDFile", "Unable to parse grid parameters");
return NULLOBJ;
}
/* -----------------------------------
Calculate the dimensions of the grid.
There is always one more grid point than number
of grid spaces in each direction.
------------------------------------ */
dims[0] = grid.numX + 1;
dims[1] = grid.numY + 1;
dims[2] = grid.numZ + 1;
/* -----------------------------------
Create the scalar dataset
----------------------------------- */
retVal = NewStructuredDataset(dataName, 3, dims, 0 );
/* ------------------------------------
Calculate grid bounds
------------------------------------ */
bounds[0] = grid.a * (real)grid.xStart / ((real)grid.xEnd-(real)grid.xStart); /*xMin */
bounds[1] = grid.a * ((real) (grid.xStart + grid.numX))/((real) (grid.xEnd-grid.xStart));
bounds[2] = grid.b * (real)grid.yStart / ((real)grid.yEnd-(real)grid.yStart); /*yMin */
bounds[3] = grid.b * ((real) (grid.yStart + grid.numY))/((real) (grid.yEnd-grid.yStart));
bounds[4] = grid.c * (real)grid.zStart / ((real)grid.zEnd-(real)grid.zStart); /*zMin */
bounds[5] = grid.c * ((real) (grid.zStart + grid.numZ))/((real) (grid.zEnd-grid.zStart));
/* ------------------------------------
Create a regular data form
------------------------------------ */
dataForm = NewRegularDataForm(formName, 3, dims, bounds);
SetDatasetForm(retVal, dataForm);
/* ------------------------------------
Fill up the dataset
depending on which index varies fastest
Keep track of minimum and maximum values as
data values are read in.
------------------------------------ */
SetCurField(FIELD1, retVal); /* Link the field to the data form */
min = PLUSINF; /* Initialize min and max to */
max = MINUSINF; /* extreme values */
if (grid.xIsFastest == true)
{
for (indices[2] = 0; indices[2] < dims[2]; (indices[2])++)
{
for (indices[1] = 0; indices[1] < dims[1]; (indices[1])++)
{
for (indices[0] = 0; indices[0] < dims[0]; (indices[0])++)
{
if (fgets(tempStr, 40, infile) != NULL)
{
if (sscanf(tempStr, "%g", &curData) == 1)
{
PutFieldComponent(FIELD1, 0, indices,curData);
if (curData < min)
min = curData;
if (curData > max)
max = curData;
}
else
{
FileFormatError("ReadGRDFile", "poor data format");
return(NULLOBJ);
}
}
else
{
FileFormatError("ReadGRDFile", "expected more data");
return(NULLOBJ);
}
}
}
}
}
else /* y varies fastest */
{
for (indices[2] = 0; indices[2] < dims[2]; (indices[2])++)
{
for (indices[0] = 0; indices[0] < dims[0]; (indices[0])++)
{
for (indices[1] = 0; indices[1] < dims[1]; (indices[1])++)
{
if (fgets(tempStr, 40, infile) != NULL)
{
if (sscanf(tempStr, "%g", &curData) == 1)
{
PutFieldComponent(FIELD1, 0, indices,curData);
if (curData < min)
min = curData;
if (curData > max)
max = curData;
}
else
{
FileFormatError("ReadGRDFile", "poor data format");
return(NULLOBJ);
}
}
else
{
FileFormatError("ReadGRDFile", "expected more data");
return(NULLOBJ);
}
}
}
}
}
/* -------------------------
Record the minimum and maximum data values
for colour palette and isosurface scales
------------------------- */
minMax[0] = min;
minMax[1] = max;
minMaxArray = NewRealArray(1, 2L);
CArray2Array(minMaxArray, minMax);
SetVar(retVal, MINMAX, minMaxArray);
RegisterDataset(retVal);
fclose(infile);
return(NULLOBJ);
}
/* ------------------------------------
Gaussian File Readers: GSN1, GSN2, GSN
The purpose of each file reader is to take as input
the coefficients and exponents of gaussian primitives,
obtained from ab initio calculations such as that produced
by G90, and approximate the molecular orbitals by a linear
combination of the primitives.
The value computed at each grid point is obtained from
the function:
f(x,y,z) = SUM(i=1..n){ d_i * c_i * g_i (zeta,x,y,z,nx,ny,nz,
Rx, Ry, Rz ) }
where:
d_i: molecular orbital coefficient
c_i: S,P,D shell coefficient of basis function
g_i: unnormalized Cartesian Gaussian function
with origin at R
zeta: orbital exponent
nx,ny,nz: determine type of shell
(see "Simplified Introduction to Ab Initio Basis Sets.
Terms and Notation", by Jan K. Labanowski, Ohio
SuperComputer Center. email: jkl@osc.edu,
JKL@OHSTPY.BITNET
see also Obara and Saika, "Efficient recursive computation
of molecular integrals over Cartesian Gaussian functions",
J.Chem. Phys. 84(7) (April 1986) p. 3964 )
GSN1 and GSN2 format are essentially the same format
(8-column and 9-column, respectively) for output from
programs other than G90. The files specify grid dimensions
and the parameters of each term in the summation.
GSN format is for G90 output. The parameters are
extracted from G90 output for a particular orbital number,
the molecular orbital computed, and the molecule
visualized in ball-and-stick form.
------------------------------------ */
/* ------------------------------------
Cartesian Gaussian function
------------------------------------ */
#ifdef PROTO
static real gaussianFunction(real x, real y, real z, real Rx, real Ry, real Rz, \
real zeta, int nx, int ny, int nz, real N)
#else
static real gaussianFunction( x, y, z, Rx, Ry, Rz, zeta, nx, ny, nz, N )
real x, y, z, Rx, Ry, Rz, zeta;
int nx, ny, nz;
real N; /* normalization constant */
#endif
{
double term1, term2, term3, term4;
double dist;
real ans;
int i;
term1 = 1.0;
for (i=0; i < nx; i++ )
term1 *= (x-Rx);
term2 = 1.0;
for (i=0; i < ny; i++)
term2 *= y-Ry;
term3 = 1.0;
for (i=0; i < nz; i++)
term3 *= z-Rz;
dist = (double) ( (x-Rx)*(x-Rx) + (y-Ry)*(y-Ry) + (z-Rz)*(z-Rz) );
term4 = exp ( (double) ( -zeta * dist ) );
ans = (real) ( ((double) N) * term1 * term2 * term3 * term4 );
return(ans);
}
/* -----------------------
oddSkipFactorial(n) = n!!
returns 1 * 3 * 5 * 7 * .... n for n > 0, n odd
returns 1 for n = -1
----------------------- */
#ifdef PROTO
static int oddSkipFactorial( int n )
#else
static int oddSkipFactorial(n)
int n;
#endif
{
int k, ans;
/* assume that n is odd */
if (n < 0 )
{
if (n == -1)
return(1);
else
return(0);
}
ans = 1;
for ( k = 1; k <= n; k += 2)
ans *= k;
return(ans);
}
#ifdef PROTO
static real normalizationConstant ( real zeta, int nx, int ny, int nz )
#else
static real normalizationConstant ( zeta, nx, ny, nz )
real zeta;
int nx, ny, nz;
#endif
{
double term1, term2, term3;
double powTerm2, fact1, fact2, fact3;
double inversePi = M_1_PI;
real ans;
term1 = pow( 2.0 * (double) zeta * inversePi , 0.75 );
powTerm2 = ((double) (nx + ny + nz)) * 0.5;
term2 = pow( 4.0 * (double) zeta, powTerm2 );
fact1 = oddSkipFactorial( 2*nx - 1 );
fact2 = oddSkipFactorial(2*ny - 1);
fact3 = oddSkipFactorial(2*nz - 1);
term3 = pow( (double) (fact1 * fact2 * fact3), -0.5);
ans = (real) (term1 * term2 * term3 );
return(ans);
}
/* --------------------------------------
ParseGSN12Header
Gets grid bounds, dimensions, and number of terms
in summation for GSN1 and GSN2 file readers
-------------------------------------- */
#ifdef PROTO
static int ParseGSN12Header( FILE *infile, real *px1, real *px2, real*py1, real *py2, real *pz1, \
real *pz2, int *pnumx, int *pnumy, int *pnumz, int *pn )
#else
static int ParseGSN12Header ( infile, px1, px2, py1, py2, pz1, pz2, pnumx, pnumy, pnumz, pn )
FILE *infile;
real *px1, *px2, *py1, *py2, *pz1, *pz2;
int *pnumx, *pnumy, *pnumz, *pn;
#endif
{
char tempStr[40];
/* ----------------------------------
Read the header information
---------------------------------- */
ReadLn(infile); /*first line is a title - ignore */
if (fgets(tempStr, 40, infile)!= NULL)
{
/* Second line should have grid bounds information */
if (6 != sscanf(tempStr, "%g %g %g %g %g %g", \
px1, px2, py1, py2, pz1, pz2))
{
FileFormatError("ReadGSNFile", "poor format for grid bounds");
return (-1);
}
}
else
{
FileFormatError("ReadGSNFile", "grid bounds expected");
return (-1);
}
if (fgets(tempStr, 40, infile)!= NULL)
{
/* Third line should have grid spacing information */
if (3 != sscanf(tempStr, "%d %d %d", pnumx, pnumy, pnumz))
{
FileFormatError("ReadGSNFile", "poor format for grid spacing");
return (-1);
}
}
else
{
FileFormatError("ReadGSNFile", "grid spacing expected");
return (-1);
}
if (fgets(tempStr, 40, infile)!= NULL)
{
/* Fourth line should have number of terms in the summation series */
if (1 != sscanf(tempStr, "%d", pn))
{
FileFormatError("ReadGSNFile", "poor format for number of terms in series");
return (-1);
}
}
else
{
FileFormatError("ReadGSNFile", "number of terms in series expected");
return (-1);
}
}
/* ----------------------------------------
ReadGSN1Parameters
---------------------------------------- */
#ifdef PROTO
static int ReadGSN1Parameters(FILE *infile, gaussianParameters *p, int n)
#else
static int ReadGSN1Parameters(infile, p, n)
FILE *infile;
gaussianParameters *p;
int n;
#endif
{
int i;
char tempStr[80];
for (i = 0; i < n; i++ )
{
if (fgets (tempStr, 80, infile) == NULL )
{
FileFormatError("ReadGSNFile", "Expected more parameters for gaussian \
function");
return(-1);
}
else if ( 8 == sscanf(tempStr, "%g %g %d %d %d %g %g %g", &(p+i)->c, &(p+i)->zeta, \
&(p+i)->nx, &(p+i)->ny, &(p+i)->nz, &(p+i)->Rx,&(p+i)->Ry, &(p+i)->Rz) )
{
(p+i)->d = 1.0; /* 8 column format OK */
}
else
{
FileFormatError("ReadGSNFile", "Poor format for gaussian parameters");
return(-1);
}
}
}
/* ---------------------------------------------
ReadGSN1File
GSN1 file reader
File format:
**************************************************
TITLE
xmin xmax ymin ymax zmin zmax
nGridx nGridy nGridz
n
c1 zeta1 nx1 ny1 nz1 Rx1 Ry1 Rz1
c2 zeta2 nx2 ny2 nz2 Rx2 Ry2 Rz2
.
.
.
cn zetan nxn nyn nzn Rxn Ryn Rzn
*************************************************
----------------------------------------------- */
#ifdef PROTO
static ObjPtr ReadGSN1File(ObjPtr reader, char *name)
#else
static ObjPtr ReadGSN1File(reader,name) /* 8 - column format */
ObjPtr reader;
char *name;
#endif
/*Reads a GSN1 file from name*/
{
FILE *infile;
ObjPtr retVal;
ObjPtr dataForm;
ObjPtr gridDataset;
long dims[3];
real bounds[6]; /* Used to define parameters of datasets */
long indices[3]; /* and dataforms */
char formName[80], dataName[80];
char *tc;
real curData;
char tempStr[40];
real min, max, minMax[2];
ObjPtr minMaxArray;
real xmin, xmax, ymin, ymax, zmin, zmax;
int ngridx, ngridy, ngridz, n;
gaussianParameters *parameters;
real x, y, z;
real xInc, yInc, zInc;
int i;
/*---------------------
Derive a dataset name from the file name
--------------------- */
strcpy(formName, name);
tc = formName;
while (*tc && (*tc != '@') && (*tc != '.'))
tc++;
*tc = '\0';
strcpy(dataName, formName);
strcat(formName, ".form");
strcat(dataName, ".data");
/* Open the file and verify that it contains appropriate data */
if ((infile = fopen(name, "r")) == NULL)
{
FileFormatError("ReadGSNFile", "File not accessible");
return NULLOBJ;
}
if(ParseGSN12Header(infile, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax, \
&ngridx, &ngridy, &ngridz, &n) == -1)
{
FileFormatError("ReadGSNFile", "Unable to parse grid parameters");
return NULLOBJ;
}
/* -----------------------------------
Allocate memory for array of function parameters and read them in
----------------------------------- */
parameters = (gaussianParameters *) Alloc ( n * sizeof (gaussianParameters) );
if (ReadGSN1Parameters(infile, parameters, n) == -1)
{
FileFormatError("ReadGSNFile", "Unable to read parameters");
return NULLOBJ;
}
/* -----------------------------------
Calculate the dimensions of the grid.
There is always one more grid point than number
of grid spaces in each direction.
------------------------------------ */
dims[0] = ngridx + 1;
dims[1] = ngridy + 1;
dims[2] = ngridz + 1;
/* -----------------------------------
Create the scalar dataset
----------------------------------- */
retVal = NewStructuredDataset(dataName, 3, dims, 0 );
/* ------------------------------------
Calculate grid bounds
------------------------------------ */
bounds[0] = xmin;
bounds[1] = xmax;
bounds[2] = ymin;
bounds[3] = ymax;
bounds[4] = zmin;
bounds[5] = zmax;
/* ------------------------------------
Create a regular data form
------------------------------------ */
dataForm = NewRegularDataForm(formName, 3, dims, bounds);
SetDatasetForm(retVal, dataForm);
/* ------------------------------------
Fill up the dataset (with x varying fastest)
generating data values as you go
Keep track of minimum and maximum values as
data values are read in.
------------------------------------ */
SetCurField(FIELD1, retVal); /* Link the field to the data form */
min = PLUSINF; /* Initialize min and max to */
max = MINUSINF; /* extreme values */
x = xmin;
y = ymin;
z = zmin;
xInc = (xmax - xmin ) / ( (real) (ngridx));
yInc = (ymax - ymin) / ( (real) (ngridy));
zInc = (zmax - zmin) / ((real) (ngridz));
for (indices[2] = 0; indices[2] < dims[2]; (indices[2])++)
{
y = ymin;
for (indices[1] = 0; indices[1] < dims[1]; (indices[1])++)
{
x = xmin;
for (indices[0] = 0; indices[0] < dims[0]; (indices[0])++)
{
curData = 0.0;
for (i=0; i < n; i++ )
curData += parameters[i].d * parameters[i].c * \
gaussianFunction(x, y, z, parameters[i].Rx, parameters[i].Ry,\
parameters[i].Rz, parameters[i].zeta, parameters[i].nx, \
parameters[i].ny, parameters[i].nz, 1.0);
/* printf("%f ", curData);*/
PutFieldComponent(FIELD1, 0, indices,curData);
if (curData < min)
min = curData;
if (curData > max)
max = curData;
x += xInc;
}
/* printf("\n"); */
y += yInc;
}
z += zInc;
}
/* -------------------------
Record the minimum and maximum data values
for colour palette and isosurface scales
------------------------- */
minMax[0] = min;
minMax[1] = max;
minMaxArray = NewRealArray(1, 2L);
CArray2Array(minMaxArray, minMax);
SetVar(retVal, MINMAX, minMaxArray);
RegisterDataset(retVal);
fclose(infile);
return(NULLOBJ);
}
/* -----------------------------------------
ReadGSN2Parameters
----------------------------------------- */
#ifdef PROTO
static int ReadGSN2Parameters(FILE *infile, gaussianParameters *p, int n)
#else
static int ReadGSN2Parameters(infile, p, n) /* 9 column */
FILE *infile;
gaussianParameters *p;
int n;
#endif
{
int i;
char tempStr[80];
for (i = 0; i < n; i++ )
{
if (fgets (tempStr, 80, infile) == NULL )
{
FileFormatError("ReadGSNFile", "Expected more parameters for gaussian \
function");
return(-1);
}
if (9 == sscanf(tempStr, "%g %g %g %d %d %d %g %g %g", &(p+i)->d, &(p+i)->c, &(p+i)->zeta, \
&(p+i)->nx, &(p+i)->ny, &(p+i)->nz, &(p+i)->Rx,&(p+i)->Ry, &(p+i)->Rz) )
{
/* 9 column format OK */
}
else
{
FileFormatError("ReadGSNFile", "Poor format for gaussian parameters");
return(-1);
}
}
}
/* ---------------------------------------------
ReadGSN2File
File format:
**************************************************
TITLE
xmin xmax ymin ymax zmin zmax
nGridx nGridy nGridz
n
d1 c1 zeta1 nx1 ny1 nz1 Rx1 Ry1 Rz1
d2 c2 zeta2 nx2 ny2 nz2 Rx2 Ry2 Rz2
.
.
.
dn cn zetan nxn nyn nzn Rxn Ryn Rzn
*************************************************
------------------------------------------------ */
#ifdef PROTO
static ObjPtr ReadGSN2File(ObjPtr reader, char *name)
#else
static ObjPtr ReadGSN2File(reader,name) /* 9 - column format */
ObjPtr reader;
char *name;
#endif
/*Reads a GSN file from name*/
{
FILE *infile;
ObjPtr retVal;
ObjPtr dataForm;
ObjPtr gridDataset;
long dims[3];
real bounds[6]; /* Used to define parameters of datasets */
long indices[3]; /* and dataforms */
char formName[80], dataName[80];
char *tc;
real curData;
char tempStr[40];
real min, max, minMax[2];
ObjPtr minMaxArray;
real xmin, xmax, ymin, ymax, zmin, zmax;
int ngridx, ngridy, ngridz, n;
gaussianParameters *parameters;
real x, y, z;
real xInc, yInc, zInc;
int i;
/*---------------------
Derive a dataset name from the file name
--------------------- */
strcpy(formName, name);
tc = formName;
while (*tc && (*tc != '@') && (*tc != '.'))
tc++;
*tc = '\0';
strcpy(dataName, formName);
strcat(formName, ".form");
strcat(dataName, ".data");
/* Open the file and verify that it contains appropriate data */
if ((infile = fopen(name, "r")) == NULL)
{
FileFormatError("ReadGSNFile", "File not accessible");
return NULLOBJ;
}
if(ParseGSN12Header(infile, &xmin, &xmax, &ymin, &ymax, &zmin, &zmax, \
&ngridx, &ngridy, &ngridz, &n) == -1)
{
FileFormatError("ReadGSNFile", "Unable to parse grid parameters");
return NULLOBJ;
}
/* -----------------------------------
Allocate memory for array of function parameters and read them in
----------------------------------- */
parameters = (gaussianParameters *) Alloc ( n * sizeof (gaussianParameters) );
if (ReadGSN2Parameters(infile, parameters, n) == -1)
{
FileFormatError("ReadGSNFile", "Unable to read parameters");
return NULLOBJ;
}
/* -----------------------------------
Calculate the dimensions of the grid.
There is always one more grid point than number
of grid spaces in each direction.
------------------------------------ */
dims[0] = ngridx + 1;
dims[1] = ngridy + 1;
dims[2] = ngridz + 1;
/* -----------------------------------
Create the scalar dataset
----------------------------------- */
retVal = NewStructuredDataset(dataName, 3, dims, 0 );
/* ------------------------------------
Calculate grid bounds
------------------------------------ */
bounds[0] = xmin;
bounds[1] = xmax;
bounds[2] = ymin;
bounds[3] = ymax;
bounds[4] = zmin;
bounds[5] = zmax;
/* ------------------------------------
Create a regular data form
------------------------------------ */
dataForm = NewRegularDataForm(formName, 3, dims, bounds);
SetDatasetForm(retVal, dataForm);
/* ------------------------------------
Fill up the dataset (with x varying fastest)
generating data values as you go
Keep track of minimum and maximum values as
data values are read in.
------------------------------------ */
SetCurField(FIELD1, retVal); /* Link the field to the data form */
min = PLUSINF; /* Initialize min and max to */
max = MINUSINF; /* extreme values */
x = xmin;
y = ymin;
z = zmin;
xInc = (xmax - xmin ) / ( (real) (ngridx));
yInc = (ymax - ymin) / ( (real) (ngridy));
zInc = (zmax - zmin) / ((real) (ngridz));
for (indices[2] = 0; indices[2] < dims[2]; (indices[2])++)
{
y = ymin;
for (indices[1] = 0; indices[1] < dims[1]; (indices[1])++)
{
x = xmin;
for (indices[0] = 0; indices[0] < dims[0]; (indices[0])++)
{
curData = 0.0;
for (i=0; i < n; i++ )
curData += parameters[i].d * parameters[i].c * \
gaussianFunction(x, y, z, parameters[i].Rx, parameters[i].Ry,\
parameters[i].Rz, parameters[i].zeta, parameters[i].nx, \
parameters[i].ny, parameters[i].nz, 1.0);
PutFieldComponent(FIELD1, 0, indices,curData);
if (curData < min)
min = curData;
if (curData > max)
max = curData;
x += xInc;
}
y += yInc;
}
z += zInc;
}
/* -------------------------
Record the minimum and maximum data values
for colour palette and isosurface scales
------------------------- */
minMax[0] = min;
minMax[1] = max;
minMaxArray = NewRealArray(1, 2L);
CArray2Array(minMaxArray, minMax);
SetVar(retVal, MINMAX, minMaxArray);
RegisterDataset(retVal);
fclose(infile);
return(NULLOBJ);
}
/* ------------------------
FtoC()
Converts a string rep. floating point number from FORTRAN to C
by replacing each 'D' with an E
--------------------------*/
#ifdef PROTO
static real FtoC(char *s1)
#else
static real FtoC(s1)
char *s1;
#endif
{
char *tmpstr;
real val;
tmpstr = s1;
while((*tmpstr != '\0') && (*tmpstr != 'D'))
tmpstr++;
if (*tmpstr == 'D')
*tmpstr = 'E';
sscanf(s1, "%f", &val);
return(val);
}
/* -----------------------------------------------
ParseGSNFile
Extracts information required to generate gaussian parameters
from G90 output.
There are six states of the parser:
state 0: Search for the keywords, "Standard orientation:\n"
Read the table and store the coordinates and
atomic number of each atom of the molecule in
atomArray, and the number of atoms in numAtoms.
state 1: Search for "Basis set in the form of general basis input:\n"
What follows will be the exponents and SPD coeffs for
the basis functions (+diffuse and/or polarization functions)
for each type of shell for each atom in order.
Store the number of shell types per atom (S, SP, P, D) in
the array, atomShells. Store the exponents, coefficients and
shell type for each shell in the array, basisSet, for all atoms
in order. The size of basisSet[] will be the total number of
shells (numShells), which is the sum of the number of
shells per atom over all atoms. The allocated size of basisSet[]
is based on the premise that the maximum number of different
shell types for a 3rd row atom is 6; the allocated size is then
6 * numAtoms.
state 2: Search for "There are %d symmetry adapted basis functions..."
There will be a variable number of lines of this form.
Add up the number of symmetries to determine the number
of molecular orbitals.
Store this value in numSym.
state 3: Search for "%d basis functions %d primitive gaussians"
These values are the number of orbital coefficients given
per orbital, and the total number of terms in the summation.
state 4: Search for "Molecular Orbital Coefficients"
which is essentially a numBasis x numSym array of coefficients,
grouped in columns of 5 with a 2-3 line header for each set.
Read to the orbital number desired, and then store the
column of coefficients in orbCoeffs[].
state 5: done
------------------------------------------------- */
#ifdef PROTO
static int ParseGSNFile(FILE *inFile, nuclearCentre **atomArray, int *numAtoms, \
int *numSym, int *numBasis, int *numPrimitives, basis **basisSet, int *numShells,\
int **atomShells,real **orbCoeff, int numOrb)
#else
static int ParseGSNFile(inFile, atomArray, numAtoms, numSym, numBasis, numPrimitives,\
basisSet, numShells, sPerA, orbCoeff, numOrb)
FILE *inFile;
nuclearCentre **atomArray;
int *numAtoms, *numSym, *numBasis, *numPrimitives;
basis **basisSet;
int *numShells;
int **atomShells; /* shells per atom */
real **orbCoeff;
int numOrb;
#endif
{
char tmpStr[80], s1[80], s2[80];
char field[3][20];
int i, num,done, count, count2,m, done2;
real x, y, z;
nuclearCentre *a; /* pointer to array of atoms */
int atomsAllocated = 10;
basis *b; /*pointer to 1D array of basis set info */
char *tmp;
int *shells; /* pointer to number of shells per atom */
int numSets, remainder, j, k, lower, upper;
real c[5]; /* temporarily holds molecular orbital coeffs */
int state = 0;
real *array; /* pointer to 1D array of MOC column */
int setDesired, columnDesired;
*numSym = 0, count=0;
SkipBlanks(inFile);
count2=0;
while (fgets(tempStr, 80, inFile)!= NULL)
{
switch (state)
{
case 0:
if (strcmp(tempStr, "Standard orientation:\n") == 0)
{ /* parse the atomic numbers and coordinates */
/* ------------------
Allocate atom array
------------------ */
a = (nuclearCentre *)Alloc(atomsAllocated * sizeof(nuclearCentre) );
if (a == NULL)
{
FileFormatError("ReadGSNFile", "Unable to allocate memory for\
atoms.");
return(-1);
}
ReadLn(inFile);
ReadLn(inFile);
ReadLn(inFile);
ReadLn(inFile);
done = FALSE;
*numAtoms = 0;
while((fgets(tempStr, 80, inFile) != NULL ) && !done)
{
if (sscanf(tempStr, "%d %d %g %g %g", &i, &num, &x, &y, &z)\
== 5)
{
/* Check if there's room in the array */
if ( *numAtoms == atomsAllocated)
{
atomsAllocated += 10;
a = (nuclearCentre *)Realloc(a, atomsAllocated\
* sizeof(nuclearCentre) );
if ( a== NULL)
{
FileFormatError("ReadGSNFile", \
"Could not allocate memory for atoms.");
return(-1);
}
}
(a+i-1)->atomicNumber = num;
(a+i-1)->x = x;
(a+i-1)->y = y;
(a+i-1)->z = z;
(*numAtoms)++;
}
else
done = TRUE;
}
*atomArray = a;
state++;
}
break;
case 1: /* read in basis set information */
if (strcmp(tempStr, "Basis set in the form of general basis input:\n") == 0)
{
/* ----------------
Allocate memory for basis set array
Assume max # shells for a third row atom is 6
Add a safety factor of 1
Assume each atom is a third row (although we
can figure this out)
Also allocate for array recording shells per atom
----------------- */
b = (basis *) Alloc ( (6+1) * (*numAtoms) * sizeof(basis) );
if (b == NULL)
{
FileFormatError("ReadGSNFile", \
"Unable to allocate memory for basis set");
return(-1); /*should print error here */
}
shells = (int *) Alloc( (*numAtoms) * sizeof(int));
count = 0; /* atom # */
i = 0; /* shell # */
while ( count < (*numAtoms)) /*read basis set for each atom */
{
m = 0; /* # shells for current atom */
ReadLn(inFile); /* first line is centre (atom) number; discard */
SkipBlanks(inFile);
if (fgets(tempStr, 80, inFile) == NULL )
{
FileFormatError("ReadGSNFile",\
"Expected more data");
return(-1);
}
while ( strcmp(tempStr, "****\n") )
{ /*loop for each shell of current atom */
sscanf(tempStr, "%s %d %f", &(b+i)->shellType, &(b+i)->numPrim,\
&(b+i)->scaleFactor);
/* -----------------
Allocate memory for exponent and coeff arrays
----------------- */
b[i].exponents = (real *) Alloc ( b[i].numPrim * sizeof(real));
b[i].s = NULL; /* occasionally not auto-initialized to NULL */
b[i].p = NULL;
b[i].d = NULL;
tmp = b[i].shellType;
while( *tmp != '\0')
{
switch(*tmp)
{
case 'S':
b[i].s = (real *) Alloc ( b[i].numPrim * sizeof(real));
break;
case 'P':
b[i].p = (real *) Alloc ( b[i].numPrim * sizeof(real));
break;
case 'D':
b[i].d = (real *) Alloc ( b[i].numPrim * sizeof(real));
break;
default:
FileFormatError("ReadGSNFile", \
"Unknown shell type");
return(-1);
break;
}
tmp++;
}
for (j = 0; j < b[i].numPrim; j++ )
{
if (fgets(tempStr, 80, inFile) == NULL )
{
FileFormatError("ReadGSNFile",\
"Expected more data");
return(-1);
}
sscanf(tempStr, "%s %s %s", field[0], field[1], field[2]);
b[i].exponents[j] = FtoC(field[0]);
k = 1; /*field array index*/
tmp = b[i].shellType;
while( *tmp != '\0')
{
switch(*tmp)
{
case 'S':
b[i].s[j] = FtoC(field[k]); k++;
break;
case 'P':
b[i].p[j] = FtoC(field[k]); k++;
break;
case 'D':
b[i].d[j] = FtoC(field[k]); k++;
break;
default:
FileFormatError("ReadGSNFile", \
"Unknown shell type");
return(-1);
break;
}
tmp++;
} /* end while (for cycling through shell type, fields)*/
} /* end for (for reading exp, coeff for each primitive)*/
i++; /* increment shell # */
m++;
SkipBlanks(inFile);
if (fgets(tempStr, 80, inFile) == NULL )
{
FileFormatError("ReadGSNFile",\
"Expected more data");
return(-1);
}
} /* end while (for reading each shell for current atom) */
shells[count]= m;
count++;
} /* end while (for reading basis sets for each atom ) */
*basisSet = b;
*numShells = i;
*atomShells = shells;
state++;
} /* end if (for checking for basis set keywords ) */
break;
case 2:
if (sscanf(tempStr, \
"There are %d symmetry adapted basis functions of %s symmetry.",\
&i, s1) == 2 )
{ /* increment the count of number of orbital symmetries
while the "There are..." pattern is matched */
*numSym = i;
SkipBlanks(inFile);
if(fgets(tempStr, 80, inFile)== NULL)
{
FileFormatError("ReadGSNFile", "Expected more data");
return(-1);
}
while(sscanf(tempStr, \
"There are %d symmetry adapted basis functions of %s symmetry.",\
&i, s1) == 2 )
{
(*numSym) += i;
SkipBlanks(inFile);
if(fgets(tempStr, 80, inFile)== NULL)
{
FileFormatError("ReadGSNFile", "Expected more data");
return(-1);
}
}
state++;
}
break;
case 3:
if (sscanf(tempStr, \
"%d basis functions %d primitive gaussians", numBasis, \
numPrimitives) == 2)
state++;
break;
case 4:
if (strcmp (tempStr, "Molecular Orbital Coefficients\n") == 0)
{
numSets = (*numSym) / 5; /* columns are printed in sets of 5 */
remainder = (*numSym) % 5; /* last set will have "remainder"# of columns */
/* ------------------
Check if orbital desired falls within range
------------------ */
if ( (numOrb < 0) || (numOrb > (*numSym-1)) )
{
FileFormatError("ReadGSNFile", "Invalid orbital selected");
return(-1);
}
array= (real *) Alloc ((*numBasis) * sizeof(real));
if (array == NULL)
return(-1);
setDesired = numOrb / 5; /* 0..*numBasis-1*/
columnDesired = numOrb % 5; /* 0..4 */
/* Read past all sets until set desired */
for ( k = 0; k < setDesired; k++)
{
/* first 2 or 3 lines of each set are header rows */
done2 = FALSE;
while (!done2 && fgets(tempStr, 80, inFile)!= NULL)
{
sscanf(tempStr, "%s", s1);
if (!strcmp(s1, "EIGENVALUES") )
done2 = TRUE;
}
for ( m = 0; m < (*numBasis); m++)
ReadLn(inFile);
}
/* now should be at correct set */
/* first 2 or 3 lines of each set are header rows */
done2 = FALSE;
while (!done2 && fgets(tempStr, 80, inFile)!= NULL)
{
sscanf(tempStr, "%s", s1);
if (!strcmp(s1, "EIGENVALUES") )
done2 = TRUE;
}
for ( m = 0; m < (*numBasis); m++)
{
if (fgets(tempStr, 80, inFile)!= NULL)
{
strcpy(s1, tempStr+20);
sscanf(s1, "%g %g %g %g %g", \
c, c+1, c+2, c+3, c+4 );
array[m] = c[columnDesired];
}
}
*orbCoeff = array;
state++;
}
break;
}
SkipBlanks(inFile);
}
if (state > 4)
return(0);
else
return(-1);
}
/* --------------------------------------------------
makeGSNParameters
Generate parameters for all primitives in summation. Pair up the
orbital exponents and SPD coefficients with the molecular orbital coefficients,
generate nx, ny, nz depending on shell type, and Rx, Ry, Rz will be
the coordinates of the centre of the current atom. (Easiest way to understand
algorithm is to generate a few primitives by hand).
----------------------------------------------------*/
#ifdef PROTO
static int makeGSNParameters( gaussianParameters **param,nuclearCentre *a, int numAtoms, \
int numSym, int numBasis, int numPrimitives, basis *basisSet, int numShells,\
int *atomShells,real *orbCoeff)
#else
static int makeGSNParameters( param,a, numAtoms, numSym, numBasis, numPrimitives,\
basisSet, numShells, sPerA, orbCoeff)
gaussianParameters **param;
nuclearCentre *a;
int numAtoms, numSym, numBasis, numPrimitives;
basis *basisSet;
int numShells;
int *atomShells; /* shells per atom */
real *orbCoeff;
#endif
{
gaussianParameters *p; /* pointer to array of parameters */
int i, j, k, count;
int mocCount; /* row index of molecular orbital coeffs */
int paramCount; /* index of parameter array */
int atomCount, shellsPerAtomCount;
char *tmp;
real pxMOC, pyMOC, pzMOC;
real dxxMOC, dyyMOC, dzzMOC, dxyMOC, dxzMOC, dyzMOC;
p = (gaussianParameters *) Alloc ( numPrimitives * sizeof (gaussianParameters));
if (p == NULL)
{
FileFormatError ("ReadGSNFile", "Unable to allocate memory for parameters");
return(-1);
}
/* ------------------------
Fill in array
------------------------- */
mocCount = 0;
paramCount = 0;
atomCount = 0;
shellsPerAtomCount = 0;
for (i = 0; i < numShells; i++)
{ /* loop through basis set in general basis set input format */
tmp = basisSet[i].shellType;
while( *tmp != '\0')
{
switch(*tmp)
{
case 'S': /* get one molecular orbital coeff (constant)*/
/* loop through #primitives for this S shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[paramCount].d = orbCoeff[mocCount];
p[paramCount].c = basisSet[i].s[j];
p[paramCount].zeta = basisSet[i].exponents[j] * basisSet[i].scaleFactor;
p[paramCount].nx = 0;
p[paramCount].ny = 0;
p[paramCount].nz = 0;
p[paramCount].Rx = a[atomCount].x;
p[paramCount].Ry = a[atomCount].y;
p[paramCount].Rz = a[atomCount].z;
paramCount++;
}
mocCount++;
break;
case 'P': /* for each primitive, get Px, Py, Pz MOC */
pxMOC = orbCoeff[mocCount];
mocCount++;
pyMOC = orbCoeff[mocCount];
mocCount++;
pzMOC = orbCoeff[mocCount];
mocCount++;
/* record where current P set begins */
count = paramCount;
/* loop through #primitives for Px, Py,Pz shells */
for ( k = 0; k < 3; k++)
{
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[paramCount].c = basisSet[i].p[j];
p[paramCount].zeta = basisSet[i].exponents[j] * basisSet[i].scaleFactor;
p[paramCount].nx = 0; /*initialize to zero*/
p[paramCount].ny = 0; /*change nx ny nz */
p[paramCount].nz = 0; /* later */
p[paramCount].Rx = a[atomCount].x;
p[paramCount].Ry = a[atomCount].y;
p[paramCount].Rz = a[atomCount].z;
paramCount++;
}
}
/* loop through #primitives for Px shell */
/* start at "count" */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = pxMOC;
p[count].nx = 1;
count++;
}
/* loop through #primitives for Py shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = pyMOC;
p[count].ny = 1;
count++;
}
/* loop through #primitives for Pz shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = pzMOC;
p[count].nz = 1;
count++;
}
break;
case 'D': /* read molecular orb. coeffs for d type shells*/
dxxMOC = orbCoeff[mocCount];
mocCount++;
dyyMOC = orbCoeff[mocCount];
mocCount++;
dzzMOC = orbCoeff[mocCount];
mocCount++;
dxyMOC = orbCoeff[mocCount];
mocCount++;
dxzMOC = orbCoeff[mocCount];
mocCount++;
dyzMOC = orbCoeff[mocCount];
mocCount++;
/* record where current D set begins */
count = paramCount;
/* loop through #primitives for all 6 D type shells */
for ( k = 0; k < 6; k++)
{
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[paramCount].c = basisSet[i].d[j];
p[paramCount].zeta = basisSet[i].exponents[j] * basisSet[i].scaleFactor;
p[paramCount].nx = 0; /*initialize to zero*/
p[paramCount].ny = 0; /*change nx ny nz */
p[paramCount].nz = 0; /* later */
p[paramCount].Rx = a[atomCount].x;
p[paramCount].Ry = a[atomCount].y;
p[paramCount].Rz = a[atomCount].z;
paramCount++;
}
}
/* loop through #primitives for Dxx shell */
/* fill in d, nx,ny,nz; start at "count" */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dxxMOC;
p[count].nx = 2;
count++;
}
/* loop through #primitives for Dyy shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dyyMOC;
p[count].ny = 2;
count++;
}
/* loop through #primitives for Dzz shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dzzMOC;
p[count].nz = 2;
count++;
}
/* loop through #primitives for Dxy shell */
/* fill in d, nx,ny,nz; start at "count" */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dxyMOC;
p[count].nx = 1;
p[count].ny = 1;
count++;
}
/* loop through #primitives for Dxz shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dxzMOC;
p[count].nx = 1;
p[count].nz = 1;
count++;
}
/* loop through #primitives for Dyz shell */
for (j = 0; j < basisSet[i].numPrim; j++)
{
p[count].d = dyzMOC;
p[count].ny = 1;
p[count].nz = 1;
count++;
}
break;
default:
FileFormatError("ReadGSNFile", \
"Unknown shell type");
return(-1);
break;
}
tmp++;
} /* end while (cycling through shell types found in current shell ) */
shellsPerAtomCount++;
if (shellsPerAtomCount == atomShells[atomCount])
{
atomCount++;
shellsPerAtomCount = 0;
}
} /* end for (looping through basis set in general basis set input format) */
*param = p;
return(0);
}
/* --------------------------------------------
makeXYZDataset
Generate unstructured dataset to visualize molecule in
ball-and-or-stick form. Taken from XYZ file reader.
(time-independent)
--------------------------------------------- */
#ifdef PROTO
static void makeXYZDataset ( char *name, nuclearCentre *a, int n)
#else
static void makeXYZDataset ( name,a, n)
char *name;
nuclearCentre *a;
int n;
#endif
{
long numAtoms; /* number of atoms per frame */
long nBonds = 0;
TwoReals *bondsBuffer = 0;
long nBondsAllocated = 0;
long dims[2];
char s[4];
char extension[5];
long i, j,k, count; /* counters*/
Bool convertToAngstroms; /* false if already in angstroms, true otherwise */
/*-------------------------------------
variables for "balls" visualization
-------------------------------------*/
/* NOTE: important to have new names for each dataset and form */
char atomsName[80], radiiName[80], tmpName[80],formName[80];
char *tc; /* terminating character */
real bounds[6];
char atomNameBuf[4];
ObjPtr formVectors, dataForm, atomicNumberDataset, radiusDataset;
real ballScaleFactor;
/* -------------------------------------
variables for bonds
------------------------------------- */
real maxStickLength;
real sum, temp;
real covalentRadius1, covalentRadius2, scaleFactor;
int bondCalcType; /* method used to calculate minimum interatomic dist for bond*/
numAtoms = n;
bondCalcType = CALC_COVALENTRADII;
scaleFactor = FUDGEFACTOR;
ballScaleFactor = 1.0;
convertToAngstroms = false;
/* -------------------------------------
make names for datasets
------------------------------------- */
strcpy (tmpName, name);
strcpy(atomsName, tmpName);
strcpy(radiiName, tmpName);
strcpy(formName, tmpName);
strcat(atomsName, ".atoms");
strcat(radiiName, ".radii");
strcat(formName, ".form");
k=1;
strcpy(tmpName, atomsName);
while (FindDatasetByName(tmpName))
{
++k;
sprintf(tmpName, "%s(%d)", atomsName,k);
}
if (k > 1)
{
sprintf(extension, "(%d)", k);
strcat(atomsName, extension);
strcat(radiiName, extension);
strcat(formName, extension);
}
/* ----------------------------------------
make bounds impossible
---------------------------------------- */
bounds[0] = bounds[2] = bounds[4] = PLUSINF;
bounds[1] = bounds[3] = bounds[5] = MINUSINF;
/* Loop through atoms to revise bounds */
for (i = 0; i < n; i++ )
{
if (a[i].x < bounds[0])
bounds[0] = a[i].x;
if (a[i].x > bounds[1] )
bounds[1] = a[i].x;
if (a[i].y < bounds[2])
bounds[2] = a[i].y;
if (a[i].y > bounds[3])
bounds[3] = a[i].y;
if (a[i].z < bounds[4])
bounds[4] = a[i].z;
if (a[i].z > bounds[5])
bounds[5] = a[i].z;
}
nBonds = 0;
nBondsAllocated = 200;
bondsBuffer = (TwoReals *) Alloc(sizeof(TwoReals) * nBondsAllocated);
for ( i = 0; i < (n-1); i++ )
{
covalentRadius1 = atomInfo[a[i].atomicNumber-1].covalentRadius;
/* --------------------------------
If either atom is missing the covalent radius data,
do not draw a bond between them.
-------------------------------- */
if (covalentRadius1 != MISRAD)
{
for (j = (i+1); j < numAtoms; j++ )
{
covalentRadius2 = atomInfo[a[j].atomicNumber-1].covalentRadius;
if ( covalentRadius2 != MISRAD)
{
sum = 0.0;
temp = a[j].x - a[i].x;
sum += temp *temp;
temp = a[j].y - a[i].y;
sum += temp * temp;
temp = a[j].z - a[i].z;
sum += temp * temp;
if (sum <= SQUARE ( (covalentRadius1 + covalentRadius2)*scaleFactor))
{
if (nBonds >= nBondsAllocated)
{
nBondsAllocated += 200;
bondsBuffer = (TwoReals *) Realloc(bondsBuffer,
sizeof(TwoReals) * nBondsAllocated);
}
bondsBuffer[nBonds][0] = i;
bondsBuffer[nBonds][1] = j;
++nBonds;
}
}
}
}
}
/* make datasets */
atomicNumberDataset = NewDataset( atomsName, 1, &numAtoms, 0);
/* this variable signals the palette creation later */
SetVar(atomicNumberDataset, UNITSNAME, NewString("Atomic number"));
radiusDataset = NewDataset( radiiName, 1, &numAtoms, 0 );
/* --------------------------------------
make a vector dataset for the form
-------------------------------------- */
formVectors = NewDataset(formName, 1, &numAtoms, 3);
dims[0] = numAtoms;
dims[1] = nBonds;
if (nBonds > 0)
{ /* one dimensional dataset (points and lines) */
dataForm = NewUnstructuredDataForm(tmpName, 1, dims, bounds,
formVectors);
}
else
{/* zero dimensional dataset (points only)*/
dataForm = NewUnstructuredDataForm(tmpName, 0, dims, bounds,
formVectors);
}
SetDatasetForm(atomicNumberDataset, dataForm);
SetDatasetForm(radiusDataset, dataForm);
/* Fill it all up */
if (nBonds)
{
/*Set the bonds*/
for (k = 0; k < nBonds; ++k)
{
Put1Edge(dataForm, k,
(long) bondsBuffer[k][0], (long) bondsBuffer[k][1]);
}
}
SetCurField(FORMFIELD, formVectors);
SetCurField(FIELD1, atomicNumberDataset);
SetCurField(FIELD2, radiusDataset);
for (i=0; i < numAtoms; i++ )
{
PutFieldComponent(FORMFIELD, 0, &i, a[i].x);
PutFieldComponent(FORMFIELD, 1, &i, a[i].y);
PutFieldComponent(FORMFIELD, 2, &i, a[i].z);
PutFieldComponent(FIELD1, 0, &i, a[i].atomicNumber ? (real)
a[i].atomicNumber : missingData);
PutFieldComponent(FIELD2, 0, &i, a[i].atomicNumber ?
atomInfo[a[i].atomicNumber-1].radius : missingData );
}
/* -------------------------
create new variables of SIZEOBJ ID
allows sizing and scaling of atomic radii
-------------------------- */
SetVar(atomicNumberDataset, SIZEOBJ, radiusDataset);
SetVar(radiusDataset, SIZEOBJ, radiusDataset);
SetVar(atomicNumberDataset, POINTSTYLE, NewInt(BS_SPHERES));
RegisterDataset ( atomicNumberDataset);
RegisterDataset ( radiusDataset );
RegisterDataset ( formVectors );
/* ---------------------------------
HACK!
Sets default ball visualization to a sphere instead
of an octohedron. SetVar of POINTSTYLE of
dataset itself doesn't seem to work.
----------------------------------- */
SetVar(visBalls, POINTSTYLE, NewInt(BS_SPHERES));
/* ---------------------------------
MORE HACK!
Set scale factor of balls' size object
---------------------------------- */
SetVar(visBalls, SIZEFACTOR, NewReal(ballScaleFactor));
}
/* ---------------------------
Default GSN values
--------------------------- */
#define GXMIN -5.0 /*default grid bounds */
#define GXMAX 5.0
#define GYMIN -5.0
#define GYMAX 5.0
#define GZMIN -5.0
#define GZMAX 5.0
#define GGRIDX 10 /* default grid spacing */
#define GGRIDY 10
#define GGRIDZ 10
#define MOLECULARORBITAL 1 /* default orbital selected is first one */
/* -------------------------------
GSN File Reader
------------------------------- */
#ifdef PROTO
static ObjPtr ReadGSNFile(ObjPtr reader, char *name)
#else
static ObjPtr ReadGSNFile(reader,name)
ObjPtr reader;
char *name;
#endif
/*Reads a GSN file from name*/
{
FILE *infile;
ObjPtr retVal;
ObjPtr dataForm;
ObjPtr gridDataset;
ObjPtr var;
long dims[3];
real bounds[6]; /* Used to define parameters of datasets */
long indices[3]; /* and dataforms */
char formName[80], dataName[80], tmpName[80];
char *tc;
real curData;
char tempStr[40];
real min, max, minMax[2];
ObjPtr minMaxArray;
real xmin, xmax, ymin, ymax, zmin, zmax;
int ngridx, ngridy, ngridz, n;
gaussianParameters *parameters;
real x, y, z;
real xInc, yInc, zInc;
int i;
/* ----------------------
new variables
---------------------- */
nuclearCentre *atoms; /* pointer to array of atom type and coordinate info */
int nAtoms, nSym; /* number of atoms and orbital symmetries */
basis *genBasis; /* points to array of general basis set */
int nGen; /* length of genBasis array (total #shells) */
int *shellsPerAtom; /* points to array that records #shells per atom */
int nBasis, nPrim; /* number of basis functions and primitive gaussians */
real *d; /* nBasis x 1 array of selected molecular orbital coefficients */
int j;
int orbitalNumber = 1; /* number of orbital to generate (0..nSym-1)*/
Bool normalize; /* true if MOC's to be normalized, false otherwise */
real sum, N; /* normalization coefficient */
/*---------------------
Derive a dataset name from the file name
--------------------- */
strcpy(tmpName, name);
tc = tmpName;
while (*tc && (*tc != '@') && (*tc != '.'))
tc++;
*tc = '\0';
strcpy(dataName, tmpName);
strcpy(formName, tmpName);
strcat(formName, ".form");
strcat(dataName, ".data");
/* -------------------------------------
get the molecular orbital selected
------------------------------------- */
var = GetIntVar("ReadGSNFile", reader, USER7);
if (!var)
orbitalNumber = MOLECULARORBITAL;
else
orbitalNumber = GetInt(var);
/* -------------------------------------
get state of normalization checkbox
------------------------------------- */
normalize = GetPredicate(reader, USER8) ? true : false;
/* -------------------------------------
get grid bounds and spacing
-------------------------------------- */
var = GetRealVar("ReadGSNFile", reader, GSNXMIN);
if (!var)
xmin = GXMIN;
else
xmin = GetReal(var);
var = GetRealVar("ReadGSNFile", reader, GSNXMAX);
if (!var)
xmax = GXMAX;
else
xmax = GetReal(var);
var = GetRealVar("ReadGSNFile", reader, GSNYMIN);
if (!var)
ymin = GYMIN;
else
ymin = GetReal(var);
var = GetRealVar("ReadGSNFile", reader, GSNYMAX);
if (!var)
ymax = GYMAX;
else
ymax = GetReal(var);
var = GetRealVar("ReadGSNFile", reader, GSNZMIN);
if (!var)
zmin = GZMIN;
else
zmin = GetReal(var);
var = GetRealVar("ReadGSNFile", reader, GSNZMAX);
if (!var)
zmax = GZMAX;
else
zmax = GetReal(var);
var = GetIntVar("ReadGSNFile", reader, GSNGRIDX);
if (!var)
ngridx = GGRIDX;
else
ngridx = GetInt(var);
var = GetIntVar("ReadGSNFile", reader, GSNGRIDY);
if (!var)
ngridy = GGRIDY;
else
ngridy = GetInt(var);
var = GetIntVar("ReadGSNFile", reader, GSNGRIDZ);
if (!var)
ngridz = GGRIDZ;
else
ngridz = GetInt(var);
/* Check if bounds are OK */
if ( (xmax < xmin) || (ymax < ymin) || (zmax < xmin) )
{
FileFormatError("ReadGSNFile", "Invalid grid bounds");
return NULLOBJ;
}
/* Open the file and verify that it contains appropriate data */
if ((infile = fopen(name, "r")) == NULL)
{
FileFormatError("ReadGSNFile", "File not accessible");
return NULLOBJ;
}
if (ParseGSNFile(infile, &atoms, &nAtoms, &nSym, &nBasis, &nPrim,\
&genBasis, &nGen, &shellsPerAtom, &d, orbitalNumber-1) == -1 )
{
FileFormatError("ReadGSNFile", "Unable to parse gaussian parameters");
return NULLOBJ;
}
for (i=0; i < nAtoms; i++ )
{
printf("%d %d %g %g %g\n", i+1, atoms[i].atomicNumber, atoms[i].x, \
atoms[i].y, atoms[i].z );
}
printf("Number of orbital symmetries: %d\n", nSym);
printf("Number of basis functions: %d\n", nBasis);
printf("Number of primitive gaussians: %d\n", nPrim);
printf("Total number of shells: %d\n", nGen);
printf("Shells per atom: \n");
for (i = 0; i < nAtoms; i++)
printf("Atom:%d Shells:%d\n", i+1, shellsPerAtom[i]);
for (i = 0; i < nGen; i++)
{
printf("%d Shell type:%s Scale factor: %f Number of primitives: %d\n",\
i, genBasis[i].shellType, genBasis[i].scaleFactor, genBasis[i].numPrim);
for (j=0; j < genBasis[i].numPrim; j++ )
{
printf("Exp:%12f ", genBasis[i].exponents[j]);
if (genBasis[i].s != NULL)
printf("S:%12f ", genBasis[i].s[j]);
if (genBasis[i].p != NULL)
printf("P:%12f ", genBasis[i].p[j]);
if (genBasis[i].d != NULL)
printf("D:%12f ", genBasis[i].d[j]);
printf("\n");
}
}
if ( normalize == true)
{
sum = 0.0;
for ( i = 0; i < nBasis; i++ )
sum += d[i] * d[i];
N = 1.0 / sqrt(sum);
for ( i = 0; i < nBasis; i++ )
d[i] = N * d[i];
printf("Normalization coefficient: %f\n", N);
}
printf("Molecular orbital coefficients for orbital #%d:\n", orbitalNumber);
for ( i = 0; i < nBasis; i++)
printf("%5d %10.5f\n", i+1, d[i]);
/* ----------------------
Now generate parameters
---------------------- */
if ( makeGSNParameters( ¶meters, atoms, nAtoms, nSym, nBasis, nPrim, \
genBasis, nGen, shellsPerAtom, d) == -1 )
{
FileFormatError("ReadGSNFile", "Unable to generate parameters");
return(NULLOBJ);
}
printf("GSN2 Parameters:\n");
for ( i = 0; i < nPrim; i ++ )
printf("%8.4f %8.4f %8.4f %5d %5d %5d %8.4f %8.4f %8.4f\n", parameters[i].d, parameters[i].c, \
parameters[i].zeta, parameters[i].nx, parameters[i].ny, parameters[i].nz, \
parameters[i].Rx,parameters[i].Ry, parameters[i].Rz );
/* -----------------------------------
Calculate the dimensions of the grid.
There is always one more grid point than number
of grid spaces in each direction.
------------------------------------ */
dims[0] = ngridx + 1;
dims[1] = ngridy + 1;
dims[2] = ngridz + 1;
/* -----------------------------------
Create the scalar dataset
----------------------------------- */
retVal = NewStructuredDataset(dataName, 3, dims, 0 );
/* ------------------------------------
Calculate grid bounds
------------------------------------ */
bounds[0] = xmin;
bounds[1] = xmax;
bounds[2] = ymin;
bounds[3] = ymax;
bounds[4] = zmin;
bounds[5] = zmax;
/* ------------------------------------
Create a regular data form
------------------------------------ */
dataForm = NewRegularDataForm(formName, 3, dims, bounds);
SetDatasetForm(retVal, dataForm);
/* ------------------------------------
Fill up the dataset (with x varying fastest)
generating data values as you go
Keep track of minimum and maximum values as
data values are read in.
------------------------------------ */
SetCurField(FIELD1, retVal); /* Link the field to the data form */
min = PLUSINF; /* Initialize min and max to */
max = MINUSINF; /* extreme values */
x = xmin;
y = ymin;
z = zmin;
xInc = (xmax - xmin ) / ( (real) (ngridx));
yInc = (ymax - ymin) / ( (real) (ngridy));
zInc = (zmax - zmin) / ((real) (ngridz));
for (indices[2] = 0; indices[2] < dims[2]; (indices[2])++)
{
y = ymin;
for (indices[1] = 0; indices[1] < dims[1]; (indices[1])++)
{
x = xmin;
for (indices[0] = 0; indices[0] < dims[0]; (indices[0])++)
{
curData = 0.0;
for (i=0; i < nPrim; i++ )
curData += parameters[i].d * parameters[i].c * \
gaussianFunction(x, y, z, parameters[i].Rx, parameters[i].Ry,\
parameters[i].Rz, parameters[i].zeta, parameters[i].nx, \
parameters[i].ny, parameters[i].nz, 1.0);
/*printf("%f ", curData);*/
PutFieldComponent(FIELD1, 0, indices,curData);
if (curData < min)
min = curData;
if (curData > max)
max = curData;
x += xInc;
}
/* printf("\n");*/
y += yInc;
}
z += zInc;
}
/* -------------------------
Record the minimum and maximum data values
for colour palette and isosurface scales
------------------------- */
minMax[0] = min;
minMax[1] = max;
minMaxArray = NewRealArray(1, 2L);
CArray2Array(minMaxArray, minMax);
SetVar(retVal, MINMAX, minMaxArray);
RegisterDataset(retVal);
fclose(infile);
/* -----------------------------
Generate XYZ dataset
----------------------------- */
makeXYZDataset( tmpName, atoms, nAtoms);
return(NULLOBJ);
}
/* --------------------------------
GSN File Reader Controls
Modified from AddNXRControls()
-------------------------------- */
#define GSN_ITEMWIDTH 225
#define GSN_MIDDLE_SEP 45
#define GSN_SMALLER_ITEM 140
#define GSN_SMALLEST_ITEM 60
#define GSN_RADIOWIDTH 400
#define GSN_BOXLEFT 325
#define GSN_BOXWIDTH 60
#ifdef PROTO
static ObjPtr AddGSNControls(ObjPtr FileReader, ObjPtr PanelContents)
#else
static ObjPtr AddGSNControls(FileReader, PanelContents)
ObjPtr FileReader, PanelContents;
#endif
{
ObjPtr titleBox, radio, checkBox, button;
ObjPtr checkbox, textbox, var;
int left, right, bottom, top;
bottom = left = MAJORBORDER;
/* Grid bounds */
/* z */
bottom += MINORBORDER;
right = left + GSN_SMALLEST_ITEM;
top = bottom + EDITBOXHEIGHT;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid z min text", "z min:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNZMIN);
if (!var)
{
SetVar(FileReader, GSNZMIN, NewReal(GZMIN));
}
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"zmin", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNZMIN,
minusInf, plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the minimum z value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLEST_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid z max text", "z max:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNZMAX);
if (!var)
SetVar(FileReader, GSNZMAX, NewReal(GZMAX));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"zmax", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNZMAX,
minusInf , plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the maximum z value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLER_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid z spacing", "Grid spacing(z):");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetIntVar("AddGSNControls", FileReader, GSNGRIDZ);
if (!var)
SetVar(FileReader, GSNGRIDZ, NewInt(GGRIDZ));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"gridz", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextIntControlWithVar(textbox, FileReader, GSNGRIDZ,
0.0, plusInf, TR_INT_ONLY +TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the grid spacing in the z direction."));
bottom = top + MINORBORDER;
left = MAJORBORDER;
top = bottom + EDITBOXHEIGHT;
right = left + GSN_SMALLEST_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid y min text", "y min:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNYMIN);
if (!var)
SetVar(FileReader, GSNYMIN, NewReal(GYMIN));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"ymin", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNYMIN,
minusInf, plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the minimum y value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLEST_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid y max text", "y max:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNYMAX);
if (!var)
SetVar(FileReader, GSNYMAX, NewReal(GYMAX));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"ymax", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNYMAX,
minusInf, plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the maximum y value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLER_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid y spacing", "Grid spacing(y):");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetIntVar("AddGSNControls", FileReader, GSNGRIDY);
if (!var)
SetVar(FileReader, GSNGRIDY, NewInt(GGRIDY));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"gridy", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextIntControlWithVar(textbox, FileReader, GSNGRIDY,
0.0, plusInf, TR_INT_ONLY +TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the grid spacing in the y direction."));
/* x */
left = MAJORBORDER;
bottom = top + MINORBORDER;
right = left + GSN_SMALLEST_ITEM;
top = bottom + EDITBOXHEIGHT;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid x min text", "x min:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNXMIN);
if (!var)
SetVar(FileReader, GSNXMIN, NewReal(GXMIN));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"xmin", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNXMIN,
minusInf, plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the minimum x value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLEST_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid x max text", "x max:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetRealVar("AddGSNControls", FileReader, GSNXMAX);
if (!var)
SetVar(FileReader, GSNXMAX, NewReal(GXMAX));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"xmax", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextRealControlWithVar(textbox, FileReader, GSNXMAX,
minusInf, plusInf,TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the maximum x value of grid bounds."));
left = right + GSN_MIDDLE_SEP;
right = left + GSN_SMALLER_ITEM;
textbox = NewTextBox(left, right, bottom, top,
0, "Grid x spacing", "Grid spacing(x):");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetIntVar("AddGSNControls", FileReader, GSNGRIDX);
if (!var)
SetVar(FileReader, GSNGRIDX, NewInt(GGRIDX));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"gridx", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextIntControlWithVar(textbox, FileReader, GSNGRIDX,
0.0, plusInf, TR_INT_ONLY +TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the grid spacing in the x direction."));
left = MAJORBORDER;
bottom = top + EDITBOXHEIGHT;
/* Normalization of coefficients checkbox */
top = bottom + CHECKBOXHEIGHT;
right = left + FRTIMEWIDTH;
checkBox = NewCheckBox(left, right, bottom, top,
"Normalize coefficients",
GetPredicate(FileReader, USER8));
SetVar(checkBox, PARENT, PanelContents);
PrefixList(PanelContents, checkBox);
bottom = top + MINORBORDER;
if (!GetVar(FileReader, USER8))
{
SetVar(FileReader, USER8, ObjFalse);
}
AssocDirectControlWithVar(checkBox, FileReader, USER8);
SetVar(checkBox, HELPSTRING,
NewString("If this box is checked, the coefficients for the \
molecular orbital selected will be normalized such that the sum of \
the squares of the coefficients equals 1."));
/* Molecular orbital textbox*/
right = left + GSN_SMALLER_ITEM;
top = bottom + EDITBOXHEIGHT;
textbox = NewTextBox(left, right, bottom, top,
0, "Molecular Orbital Text", "Molecular Orbital #:");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
left = right;
right = left + GSN_BOXWIDTH;
var = GetIntVar("AddGSNControls", FileReader, USER7);
if (!var)
SetVar(FileReader, USER7, NewReal(MOLECULARORBITAL));
textbox = NewTextBox(left, right, bottom, top,
EDITABLE + WITH_PIT + ONE_LINE,
"Molecular Orbital #", "0");
SetVar(textbox, PARENT, PanelContents);
PrefixList(PanelContents, textbox);
SetTextAlign(textbox, RIGHTALIGN);
AssocTextIntControlWithVar(textbox, FileReader, USER7,
1.0, plusInf, TR_INT_ONLY + TR_NE_TOP);
SetVar(textbox, HELPSTRING,
NewString("This value is the molecular orbital # selected."));
return NULLOBJ;
}
/* ------------------------------------
Initialize SIMS File Readers
------------------------------------ */
#ifdef PROTO
void InitSIMSFiles(void)
#else
void InitSIMSFiles()
#endif
{
ObjPtr fileReader;
fileReader = NewFileReader("XYZ");
SetVar(fileReader, EXTENSION, NewString("xyz"));
SetVar(fileReader, HELPSTRING, \
NewString("This file reader takes molecular data in xyz format as specified by\
the Minnesota Supercomputer Center's XMol. Format specification follows: \
There may be multiple frames for animation. For each frame, the first line \
must have an integer specifying the number of atoms, the second line is reserved \
for a title (possibly just a blank line), and one line for each atom in the form: \
name x y z (charge) (vectorX) (vectorY) (vectorZ). A number of frames may \
follow. Charge and/or field vector \
may be specified but are ignored by the reader. It is assumed that the number of \
atoms will be the same from frame to frame. The file reader produces three \
datasets, with the extensions: .atoms, .radii, .form. The radii and form datasets \
may be ignored by the user. The atoms dataset may be visualized in ball and or \
stick form. Developed \
at the Steacie Institute for Molecular Sciences at the National Research Council \
of Canada."));
SetMethod(fileReader, READALL, ReadXYZFile);
SetMethod(fileReader, ADDCONTROLS, AddXYZControls);
/* -------------------------------------
set USER1 to be the minimum distance required for a bond
------------------------------------- */
SetVar(fileReader, USER1, NewReal(MAXSTICKLENGTH));
/* --------------------------------------
set USER3 to be radio button group for bond calculation
-------------------------------------- */
SetVar(fileReader, USER3, NewInt(CALC_COVALENTRADII));
/* ---------------------------------------
set USER4 to be the scaling factor used in covalent radii calculation
--------------------------------------- */
SetVar(fileReader, USER4, NewReal(FUDGEFACTOR));
/* ---------------------------------------
set USER5 to be pre-set scaling factor of sphere radius
e.g. want to set this low for reading in a lot of organic molecules
--------------------------------------- */
SetVar(fileReader, USER5, NewReal(1.0));
/*----------------------------------------
set USER6 to be checkbox for conversion from atomic
length units to angstroms
---------------------------------------- */
SetVar(fileReader, USER6, ObjFalse);
/* save setting stuff */
AddSnapVar(fileReader, USER1);
AddSnapVar(fileReader, USER2);
AddSnapVar(fileReader, USER3);
AddSnapVar(fileReader, USER4);
AddSnapVar(fileReader, USER5);
AddSnapVar(fileReader, USER6);
ApplySavedSettings(fileReader);
/* -----------------------------------------
Read in user-defined atoms if any exist
----------------------------------------- */
numExtraXYZSymbols = ReadExtraXYZSymbolTable();
if (numExtraXYZSymbols== -1)
FileFormatError("ReadExtraXYZSymbolTable", "Poor format for user defined XYZ \
symbol table");
fileReader = NewFileReader("GRD");
SetVar(fileReader, EXTENSION, NewString("grd"));
SetVar(fileReader, HELPSTRING, \
NewString("This file reader takes 3D grid data in .grd format as generated by \
BioSym's DMol PLOT command (see p.B31-B35 of DMol user manual). \
Developed at the Steacie Institute for Molecular Sciences at the \
National Research Council of Canada."));
SetMethod(fileReader, READALL, ReadGRDFile);
fileReader = NewFileReader("GSN1");
SetVar(fileReader, EXTENSION, NewString("gsn1"));
SetVar(fileReader, HELPSTRING, \
NewString("The purpose of the GSN1 file reader is to take \
as input the coefficients and exponents of gaussian primitives, \
obtained from ab initio calculations such as that produced \
by G92, and approximate the molecular orbitals by a linear \
combination of the primitives. \n\n \
The value computed at each grid point is obtained from \
the function:\n\n f(x,y,z) = SUM(i=1..n){ c_i * g_i (zeta,x,y,z,nx,ny,nz, \
Rx, Ry, Rz ) }\n \
The GSN1 file must be of the form:\n \
**************************************************\n \
TITLE\n \
xmin xmax ymin ymax zmin zmax\n \
nGridx nGridy nGridz\n \
n\n \
c1 zeta1 nx1 ny1 nz1 Rx1 Ry1 Rz1\n \
c2 zeta2 nx2 ny2 nz2 Rx2 Ry2 Rz2\n \
.\n.\n.\n \
cn zetan nxn nyn nzn Rxn Ryn Rzn\n \
*************************************************\n \
Developed at the Steacie Institute for Molecular Sciences at the \
National Research Council of Canada."));
SetMethod(fileReader, READALL, ReadGSN1File);
fileReader = NewFileReader("GSN2");
SetVar(fileReader, EXTENSION, NewString("gsn2"));
SetVar(fileReader, HELPSTRING, \
NewString("The purpose of the GSN2 file reader is to take \
as input the coefficients and exponents of gaussian primitives, \
obtained from ab initio calculations such as that produced \
by G92, and approximate the molecular orbitals by a linear \
combination of the primitives. \n\n \
The value computed at each grid point is obtained from \
the function:\n\n f(x,y,z) = SUM(i=1..n){ d_i * c_i * g_i (zeta,x,y,z,nx,ny,nz, \
Rx, Ry, Rz ) }\n \
The GSN2 file must be of the form:\n \
**************************************************\n \
TITLE\n \
xmin xmax ymin ymax zmin zmax\n \
nGridx nGridy nGridz\n \
n\n \
d1 c1 zeta1 nx1 ny1 nz1 Rx1 Ry1 Rz1\n \
d2 c2 zeta2 nx2 ny2 nz2 Rx2 Ry2 Rz2\n \
.\n.\n.\n \
dn cn zetan nxn nyn nzn Rxn Ryn Rzn\n \
*************************************************\n \
Developed at the Steacie Institute for Molecular Sciences at the \
National Research Council of Canada."));
SetMethod(fileReader, READALL, ReadGSN2File);
fileReader = NewFileReader("GSN");
SetVar(fileReader, EXTENSION, NewString("gsn"));
SetVar(fileReader, HELPSTRING, \
NewString("The GSN file reader will extract the coefficients \
and exponents of gaussian primitives from a G92 output file, and \
approximate the molecular orbitals by a linear combination of the \
primitives. In addition, it will take the atomic coordinate information \
in the G92 output file to generate a .atoms dataset for visualizing \
the molecule in ball-and-or-stick form. The combined visualization \
of the molecular orbitals and the ball/stick molecule can be \
quite informative. \n\nGaussian92 File Specifications\n \
===============================\n \
The GSN file reader can read standard N-M1G basis sets, with\
or without additional polarization or diffuse functions.\
The reader will recognize S,P,D shell types, but not F orbitals.\
\n \
To create an output file that may be read by the GSN reader,\
the command line of the Gaussian92 input must contain\
\na) the keyword to print the GAUSSIAN function table in \
GenBas format:\niop(3/24=10)\n \
b) the keyword to print eigenvalues and eigenvectors:\n \
Pop=reg {or Pop=full}\n \
Developed at the Steacie Institute for Molecular Sciences at the \
National Research Council of Canada."));
SetMethod(fileReader, READALL, ReadGSNFile);
SetMethod(fileReader, ADDCONTROLS, AddGSNControls);
/* -------------------------------------
set USER7 to be the molecular orbital selected
set USER8 to be checkbox for normalization of
molecular orbital coefficients (default: off)
------------------------------------- */
SetVar(fileReader, USER7, NewInt(MOLECULARORBITAL));
SetVar(fileReader, USER8, ObjFalse);
/* --------------------------------------
grid bounds/spacing variables
-------------------------------------- */
SetVar(fileReader, GSNXMIN, NewReal(GXMIN));
SetVar(fileReader, GSNXMAX, NewReal(GXMAX));
SetVar(fileReader, GSNYMIN, NewReal(GYMIN));
SetVar(fileReader, GSNYMAX, NewReal(GYMAX));
SetVar(fileReader, GSNZMIN, NewReal(GZMIN));
SetVar(fileReader, GSNZMAX, NewReal(GZMAX));
SetVar(fileReader, GSNGRIDX, NewInt(GGRIDX));
SetVar(fileReader, GSNGRIDY, NewInt(GGRIDY));
SetVar(fileReader, GSNGRIDZ, NewInt(GGRIDZ));
/* save setting stuff */
AddSnapVar(fileReader, USER7);
AddSnapVar(fileReader, USER8);
AddSnapVar(fileReader, GSNXMIN);
AddSnapVar(fileReader, GSNXMAX);
AddSnapVar(fileReader, GSNYMIN);
AddSnapVar(fileReader, GSNYMAX);
AddSnapVar(fileReader, GSNZMIN);
AddSnapVar(fileReader, GSNZMAX);
AddSnapVar(fileReader, GSNGRIDX);
AddSnapVar(fileReader, GSNGRIDY);
AddSnapVar(fileReader, GSNGRIDZ);
ApplySavedSettings(fileReader);
}
/* ------------------------------------
Kills any SIMS File Handling Routines
------------------------------------ */
void KillSIMSFiles()
{
}